﻿using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace CsharpTool.Common
{
    [ApiController]
    [Route("[controller]")]
    public class StreamApiController : ControllerBase
    {
        private readonly IHubContext<ChatHub> _hubContext;

        /// <summary>
        /// ctor
        /// </summary>
        public StreamApiController(IHubContext<ChatHub> hubContext)
        {
            _hubContext = hubContext;
        }

        [HttpGet("sse")]
        public async Task ServerSentEventAsync()
        {
            Response.ContentType = "text/event-stream";
            Response.Headers.CacheControl = "no-cache";
            Response.Headers.Connection = "keep-alive";

            var messages = new string[] { "Hello, ", "this is an SSE message!", "Here's another message." };
            foreach (var message in messages)
            {
                await Response.WriteAsync($"data: {message}\n\n");
                await Response.Body.FlushAsync();
                await Task.Delay(1000);
            }

            #region sse html+js
            var html = @"
                      <div id=""messages""></div>
                      <script>
                        // 创建SSE连接
                        const eventSource = newEventSource('https://localhost:7148/WeatherForecast/sse');

                        // 监听消息事件
                        eventSource.onmessage = function (event) {{
                          const messageContainer = document.getElementById('messages');
                          const newMessage = document.createElement('p');
                          newMessage.textContent = event.data;
                          messageContainer.appendChild(newMessage);

                          // 滚动到最新消息
                          messageContainer.scrollTop = messageContainer.scrollHeight;
                        }};

                        // 监听打开连接事件
                        eventSource.onopen = function () {{
                          console.log(""连接已打开"");
                        }};

                        // 监听错误事件
                        eventSource.onerror = function (error) {{
                          console.error(""发生错误"", error);
                          eventSource.close(); // 关闭连接
                        }};
                      </script>";
            #endregion
        }

        [HttpGet("ws")]
        public async Task WebSocketAsync()
        {
            var messages = new string[] { "Hello, ", "this is an SSE message!", "Here's another message." };
            foreach (var message in messages)
            {
                await _hubContext.Clients.All.SendAsync("ReceiveMessage", message);
                await Task.Delay(1000);
            }

            #region singalr html+js
            var html = @"
                      <div id=""messages""></div>
                      <script>
                        // 创建WebSocket连接
                        const ws = newWebSocket('https://localhost:7148/WeatherForecast/ws');

                        // 监听消息事件
                        ws.onmessage = function (event) {{
                          const messageContainer = document.getElementById('messages');
                          const newMessage = document.createElement('p');
                          newMessage.textContent = event.data;
                          messageContainer.appendChild(newMessage);

                         // 滚动到最新消息";
            var html1 = @"
                        const connection = new signalR.HubConnectionBuilder()
                            .withUrl(""/chatHub"")
                            .build();

                        connection.on(""ReceiveMessage"", function (message) {
                            console.log(""Received message: "", message);
                        });

                        connection.start().catch(function (err) {
                            return console.error(err.toString());
                        });";
            #endregion
        }

        #region SingalR Class
        public class ChatHub : Hub
        {
            public async Task SendMessage(string user, string message)
            {
                await Clients.All.SendAsync("broadcastMessage", user, message);
            }
        }
        #endregion

        [HttpGet("chunked")]
        public async Task ChunkedResponse()
        {
            Response.ContentType = "text/plain";
            var phrases = new string[] { "This is ", "a chunked ", "response! ", "Enjoy it." };

            foreach (var phrase in phrases)
            {
                byte[] buffer = Encoding.UTF8.GetBytes(phrase);
                await Response.Body.WriteAsync(buffer);
                await Response.Body.FlushAsync();
                await Task.Delay(1000);
            }

            var html = @"
                        <body>
                          <div id=""content""></div>
                          <script>
                            fetch('https://localhost:7128/WeatherForecast/ChunkedResponse/chunked')
                              .then(response => {
                                const reader = response.body.getReader();
                                const decoder = newTextDecoder();
                                const contentDiv = document.getElementById('content');

                                functionreadChunk () {
                                  reader.read().then(({ done, value }) => {
                                    if (done) return;
                                    contentDiv.innerHTML += decoder.decode(value, { stream: true }) + '<br>';
                                    readChunk();  // 继续读取下一个数据块
                                  });
                                }

                                readChunk();
                              });
                          </script>
                        </body>";
        }
    }
}
